home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / sun3.md / devMouse.c < prev    next >
C/C++ Source or Header  |  1990-10-11  |  19KB  |  709 lines

  1. /* 
  2.  * devMouse.c --
  3.  *
  4.  *    This file implements the "mouse" device, which is used by
  5.  *    window systems to find out about keyboard and mouse events.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/kernel/dev/sun3.md/RCS/devMouse.c,v 9.8 90/10/11 15:37:38 mendel Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include <sprite.h>
  22. #include <dev.h>
  23. #include <devAddrs.h>
  24. #include <dev/mouse.h>
  25. #include <errno.h>
  26. #include <mouse.h>
  27. #include <fs.h>
  28. #include <fsio.h>
  29. #include <list.h>
  30. #include <status.h>
  31. #include <stdlib.h>
  32. #include <timer.h>
  33. #include <tty.h>
  34. #include <ttyAttach.h>
  35. #include <z8530.h>
  36. #include <console.h>
  37. #include <user/bstring.h>
  38. #include <fsioDevice.h>
  39. /*
  40.  * For synchronization, use devTty's monitor lock (this module is
  41.  * so closely intertwined with devTty.c that this is the only logical
  42.  * approach).
  43.  */
  44.  
  45. #define LOCKPTR (&devTtyLock)
  46.  
  47. /*
  48.  * One of the structures below is dynamically allocated for each
  49.  * input event.
  50.  */
  51.  
  52. typedef struct {
  53.     List_Links links;        /* Pointers to next & previous items. */
  54.     Mouse_Event event;        /* Event. */
  55. } Event;
  56.  
  57. static List_Links eventList;    /* List of pending input events. */
  58. static int listCount;        /* Number of elements in list. */
  59. #define MAX_LIST_LENGTH 500
  60.  
  61. /*
  62.  * Other information about mouse device.  This file is strongly
  63.  * entwined with devTty.c in that this file only uses SOME of the
  64.  * devTty features (namely the ability to buffer input characters
  65.  * and process them at background level).  The output portion of
  66.  * the mouse channel is not used:  output on the mouse device goes
  67.  * to the keyboard channel.
  68.  */
  69.  
  70. static DevTty mouseTty;            /* Information used by devTty.c. */
  71. static DevZ8530 mouse = {        /* Information used by device driver. */
  72.     "mouse",                /* name */
  73.     (DevZ8530Device *) DEV_MOUSE_ADDR,    /* address */
  74.     &mouseTty,                /* ttyPtr */
  75.     DEV_UART_VECTOR,            /* vector */
  76.     1200,                /* baud */
  77.     WRITE3_RX_8BIT,            /* wr3 */
  78.     WRITE5_TX_8BIT,            /* wr5 */
  79.     DevTtyInputChar,            /* inputProc */
  80.     (ClientData) &mouseTty,        /* inputData */
  81.     DevTtyOutputChar,            /* outputProc */
  82.     (ClientData) &mouseTty,        /* outputData */
  83.     0,                    /* oldRr0 */
  84.     Z_CHANNEL_B | Z_INACTIVE        /* flags */
  85. };
  86.  
  87. static Fs_NotifyToken token;        /* Used for Fs call-backs to wake up
  88.                      * waiting processes. */
  89. static volatile int outputBuffer = -1;    /* One-character output buffer shared
  90.                      * without explicit synchronization
  91.                      * between background and interrupt-
  92.                      * level procedures.  -1 means buffer
  93.                      * empty;  otherwise it contains a
  94.                      * single character to be output. */
  95. static DevZ8530 *keyboardPtr;        /* Information about the keyboard's
  96.                      * UART (needed to start up output). */
  97.  
  98. /*
  99.  * Forward declarations to procedures declared later in this file:
  100.  */
  101.  
  102. static void MouseDelayedClose _ARGS_((ClientData clientData,
  103.                                      Proc_CallInfo *callInfoPtr));
  104. static void MouseInputProc _ARGS_((ClientData dummy, int value));
  105. static void KbdInputProc _ARGS_((ClientData dummy, int value));
  106. static int MouseOutputProc _ARGS_((void));
  107.  
  108.  
  109. /*
  110.  *----------------------------------------------------------------------
  111.  *
  112.  * DevMouseInit --
  113.  *
  114.  *    Called during bootstrapping to initialize mouse-related
  115.  *    things.
  116.  *
  117.  * Results:
  118.  *    None.
  119.  *
  120.  * Side effects:
  121.  *    Resets the serial device.
  122.  *
  123.  *----------------------------------------------------------------------
  124.  */
  125.  
  126. void
  127. DevMouseInit()
  128. {
  129.     DevZ8530RawProc(&mouse, TD_RAW_SHUTDOWN, 0, (char *) NULL,
  130.         0, (char *) NULL);
  131. }
  132.  
  133. /*
  134.  *----------------------------------------------------------------------
  135.  *
  136.  * DevMouseOpen --
  137.  *
  138.  *    Called through devFsOpTable to open the mouse device.
  139.  *    Initializes the device and activates it so that it's ready
  140.  *    to return input.
  141.  *
  142.  * Results:
  143.  *    A standard Sprite ReturnStatus.
  144.  *
  145.  * Side effects:
  146.  *    The mouse-related devices will be "turned on" if they aren't
  147.  *    already, which may involve setting up interrupt handlers.
  148.  *
  149.  *----------------------------------------------------------------------
  150.  */
  151.  
  152. /* ARGSUSED */
  153. ENTRY ReturnStatus
  154. DevMouseOpen(devicePtr, useFlags, notifyToken, flagsPtr)
  155.     Fs_Device *devicePtr;    /* Information about device (e.g. type
  156.                  * and unit number). */
  157.     int useFlags;        /* Flags for the stream being opened:
  158.                  * OR'ed combination of FS_READ and
  159.                  * FS_WRITE. */
  160.     Fs_NotifyToken notifyToken;    /* Used for Fs call-back to notify waiting
  161.                  * processes that the terminal is ready. */
  162.     int *flagsPtr;            /* OUT: Device IO flags */
  163. {
  164.     if (devicePtr->unit != 0) {
  165.     return Compat_MapToSprite(ENXIO);
  166.     }
  167.  
  168.     LOCK_MONITOR;
  169.  
  170.     mouseTty.openCount += 1;
  171.     if (mouseTty.openCount == 1) {
  172.     token = notifyToken;
  173.     keyboardPtr = DevGrabKeyboard(KbdInputProc, (ClientData) 0,
  174.         MouseOutputProc, (ClientData) 0);
  175.     mouseTty.insertOutput = 0;
  176.     mouseTty.extractOutput = 0;
  177.     mouseTty.rawProc = DevZ8530RawProc;
  178.     mouseTty.activateProc = DevZ8530Activate;
  179.     mouseTty.rawData = (ClientData) &mouse;
  180.     mouseTty.inputProc = MouseInputProc;
  181.     mouseTty.inputData = 0;
  182.     mouseTty.consoleFlags = 0;
  183.     List_Init(&eventList);
  184.     (*mouseTty.activateProc)(&mouse);
  185.     }
  186.  
  187.     UNLOCK_MONITOR;
  188.     return SUCCESS;
  189. }
  190.  
  191. /*
  192.  *----------------------------------------------------------------------
  193.  *
  194.  * DevMouseRead --
  195.  *
  196.  *    Called through devFsOpTable to read from the mouse device.
  197.  *
  198.  * Results:
  199.  *    A standard Sprite ReturnStatus.  Characters are stored at
  200.  *    *readPtr->buffer, and the fields of *replyPtr are modified
  201.  *    to describe what happened.  The mouse must be read in even
  202.  *    multiples of the size of Mouse_Event.
  203.  *
  204.  * Side effects:
  205.  *    Information may be removed from the mouse input queue.
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209.  
  210. /* ARGSUSED */
  211. ENTRY ReturnStatus
  212. DevMouseRead(devicePtr, readPtr, replyPtr)
  213.     Fs_Device *devicePtr;    /* Information about device. */
  214.     register Fs_IOParam *readPtr;    /* Input parameters. */
  215.     register Fs_IOReply *replyPtr;    /* Place to store return information. */
  216. {
  217.     int stillToDo;
  218.     char *bufPtr;
  219.  
  220.     replyPtr->length = 0;
  221.     stillToDo = readPtr->length;
  222.     bufPtr = (char *) readPtr->buffer;
  223.  
  224.     /*
  225.      * Make sure the buffer is large enough to hold at least one
  226.      * event.
  227.      */
  228.  
  229.     if (stillToDo < sizeof(Mouse_Event)) {
  230.     return Compat_MapToSprite(EINVAL);
  231.     }
  232.  
  233.     LOCK_MONITOR;
  234.  
  235.  
  236.     if (List_IsEmpty(&eventList)) {
  237.     UNLOCK_MONITOR;
  238.     return Compat_MapToSprite(EWOULDBLOCK);
  239.     }
  240.     while ((stillToDo >= sizeof(Mouse_Event)) && !List_IsEmpty(&eventList)) {
  241.     register Event *eventPtr;
  242.  
  243.     eventPtr = (Event *) List_First(&eventList);
  244.     List_Remove(&eventPtr->links);
  245.     bcopy((char *) &eventPtr->event, (char *) bufPtr, sizeof(Mouse_Event));
  246.     bufPtr += sizeof(Mouse_Event);
  247.     stillToDo -= sizeof(Mouse_Event);
  248.     replyPtr->length += sizeof(Mouse_Event);
  249.     free((char *) eventPtr);
  250.     listCount -= 1;
  251.     }
  252.     UNLOCK_MONITOR;
  253.     return SUCCESS;
  254. }
  255.  
  256. /*
  257.  *----------------------------------------------------------------------
  258.  *
  259.  * DevMouseWrite --
  260.  *
  261.  *    Called through devFsOpTable to write to the mouse device.
  262.  *
  263.  * Results:
  264.  *    A standard Sprite ReturnStatus.  Fields of *replyPtr are
  265.  *    modified to indicate what happened in the write operation.
  266.  *
  267.  * Side effects:
  268.  *    Information may be added to the output buffer for the keyboard.
  269.  *
  270.  *----------------------------------------------------------------------
  271.  */
  272.  
  273. /* ARGSUSED */
  274. ReturnStatus
  275. DevMouseWrite(devicePtr, writePtr, replyPtr)
  276.     Fs_Device *devicePtr;        /* Information about device. */
  277.     register Fs_IOParam *writePtr;    /* Input parameters. */
  278.     register Fs_IOReply *replyPtr;    /* Place to store result info. */
  279. {
  280.     ReturnStatus status = SUCCESS;
  281.     int stillToDo;
  282.     char *bufPtr;
  283.  
  284.     LOCK_MONITOR;
  285.  
  286.     replyPtr->length = 0;
  287.     stillToDo = writePtr->length;
  288.     bufPtr = (char *) writePtr->buffer;
  289.     while (stillToDo != 0) {
  290.     if (outputBuffer != -1) {
  291.         status = FS_WOULD_BLOCK;
  292.         break;
  293.     }
  294.     outputBuffer = (*((char *) bufPtr)) & 0xff;
  295.     bufPtr++;
  296.     stillToDo--;
  297.     replyPtr->length++;
  298.     DevZ8530RawProc(keyboardPtr, TD_RAW_OUTPUT_READY, 0, (char *) NIL,
  299.         0, (char *) NIL);
  300.     }
  301.     UNLOCK_MONITOR;
  302.     return status;
  303. }
  304.  
  305. /*
  306.  *----------------------------------------------------------------------
  307.  *
  308.  * DevMouseIOControl --
  309.  *
  310.  *    Called through devFsOpTable to perform IOControl operations on
  311.  *    the mouse device.
  312.  *
  313.  * Results:
  314.  *    A standard Sprite ReturnStatus.
  315.  *
  316.  * Side effects:
  317.  *    None.
  318.  *
  319.  *----------------------------------------------------------------------
  320.  */
  321.  
  322. /* ARGSUSED */
  323. ReturnStatus
  324. DevMouseIOControl(devicePtr, iocPtr, replyPtr)
  325.     Fs_Device *devicePtr;        /* Information about device. */
  326.     Fs_IOCParam *iocPtr;        /* Parameter information (buffer sizes
  327.                      * etc.). */
  328.     Fs_IOReply *replyPtr;        /* Place to store result information. */
  329. {
  330.     return Compat_MapToSprite(ENOTTY);
  331. }
  332.  
  333. /*
  334.  *----------------------------------------------------------------------
  335.  *
  336.  * DevMouseSelect --
  337.  *
  338.  *    Called through devFsOpTable to perform select-related functions
  339.  *    on the mouse device.
  340.  *
  341.  * Results:
  342.  *    Always SUCCESS.  The values at *readPtr, *writePtr, and *exceptPtr
  343.  *    get set to zero if the device is NOT readable, or writable, or
  344.  *    exception-pending, respectively.
  345.  *
  346.  * Side effects:
  347.  *    None.
  348.  *
  349.  *----------------------------------------------------------------------
  350.  */
  351.  
  352. /* ARGSUSED */
  353. ENTRY ReturnStatus
  354. DevMouseSelect(devicePtr, readPtr, writePtr, exceptPtr)
  355.     Fs_Device *devicePtr;    /* Information about device. */
  356.     int *readPtr;        /* Set to zero if device not readable. */
  357.     int *writePtr;        /* Set to zero if device not writable. */
  358.     int *exceptPtr;        /* Set to zero if no exception pending on
  359.                  * device. */
  360. {
  361.     LOCK_MONITOR;
  362.     if (List_IsEmpty(&eventList)) {
  363.     *readPtr = 0;
  364.     }
  365.     if (outputBuffer != -1) {
  366.     *writePtr = 0;
  367.     }
  368.     *exceptPtr = 0;
  369.     UNLOCK_MONITOR;
  370.     return SUCCESS;
  371. }
  372.  
  373. /*
  374.  *----------------------------------------------------------------------
  375.  *
  376.  * DevMouseClose --
  377.  *
  378.  *    Called through devFsOpTable when the mouse device is closed.
  379.  *
  380.  * Results:
  381.  *    A standard Sprite return status.
  382.  *
  383.  * Side effects:
  384.  *    Data structures get cleaned up and possibly deallocated.
  385.  *
  386.  *----------------------------------------------------------------------
  387.  */
  388.  
  389. /* ARGSUSED */
  390. ReturnStatus
  391. DevMouseClose(devicePtr, useFlags, openCount, writerCount)
  392.     Fs_Device *devicePtr;        /* Information about device. */
  393.     int useFlags;            /* Indicates whether stream being
  394.                      * closed was open for reading and/or
  395.                      * writing:  OR'ed combination of
  396.                      * FS_READ and FS_WRITE. */
  397.     int openCount;            /* # of opens still active for this
  398.                      * device. */
  399.     int writerCount;            /* # of active opens that permit
  400.                      * writing. */
  401. {
  402.     LOCK_MONITOR;
  403.     mouseTty.openCount -= 1;
  404.     if (mouseTty.openCount == 0) {
  405.     while (!List_IsEmpty(&eventList)) {
  406.         List_Links *eventPtr;
  407.     
  408.         eventPtr = List_First(&eventList);
  409.         List_Remove(eventPtr);
  410.         free((char *) eventPtr);
  411.     }
  412.     
  413.     /*
  414.      * If I/O is still in progress, delay shutting down the device
  415.      * until the I/O completes.
  416.      */
  417.     
  418.     if (outputBuffer == -1) {
  419.         DevReleaseKeyboard();
  420.         (void) (*mouseTty.rawProc)(mouseTty.rawData, TD_RAW_SHUTDOWN, 0,
  421.             (char *) NULL, 0, (char *) NULL);
  422.     }
  423.     }
  424.     UNLOCK_MONITOR;
  425.     return SUCCESS;
  426. }
  427.  
  428. /*
  429.  *----------------------------------------------------------------------
  430.  *
  431.  * MouseDelayedClose --
  432.  *
  433.  *    Background-level procedure to complete the device close if
  434.  *    it couldn't be completed at close-time because I/O was still
  435.  *    in progress.
  436.  *
  437.  * Results:
  438.  *    None.
  439.  *
  440.  * Side effects:
  441.  *    The mouse gets shutdown and the keyboard reverts to normal
  442.  *    operation.
  443.  *
  444.  *----------------------------------------------------------------------
  445.  */
  446.  
  447. static void
  448. MouseDelayedClose(clientData, callInfoPtr)
  449.     ClientData     clientData;        /* Not used. */
  450.     Proc_CallInfo *callInfoPtr;         /* Not used. */
  451. {
  452.     LOCK_MONITOR;
  453.     if (mouseTty.openCount == 0) {
  454.     DevReleaseKeyboard();
  455.     (void) (*mouseTty.rawProc)(mouseTty.rawData, TD_RAW_SHUTDOWN, 0,
  456.         (char *) NULL, 0, (char *) NULL);
  457.     }
  458.     UNLOCK_MONITOR;
  459. }
  460.  
  461. /*
  462.  *----------------------------------------------------------------------
  463.  *
  464.  * DevMouseInterrupt --
  465.  *
  466.  *    This procedure is invoked whenever an interrupt occurs
  467.  *    for one of the Z8530 chips.
  468.  *
  469.  * Results:
  470.  *    None.
  471.  *
  472.  * Side effects:
  473.  *    The Z8530 interrupt handler gets invoked to see if anything
  474.  *    happened related to the mouse UART.
  475.  *
  476.  *----------------------------------------------------------------------
  477.  */
  478.  
  479. void
  480. DevMouseInterrupt()
  481. {
  482.     DevZ8530Interrupt((ClientData)&mouse);
  483. }
  484.  
  485. /*
  486.  *----------------------------------------------------------------------
  487.  *
  488.  * MouseInputProc --
  489.  *
  490.  *    This procedure is invoked at background level (i.e in a kernel
  491.  *    process) to handle input characters from the mouse UART.  The
  492.  *    caller is expected to have acquired the tty monitor lock.
  493.  *
  494.  * Results:
  495.  *    None.
  496.  *
  497.  * Side effects:
  498.  *    The input character is converted to an event, which is then
  499.  *    enqueued on an input queue.
  500.  *
  501.  *----------------------------------------------------------------------
  502.  */
  503.  
  504. /* ARGSUSED */
  505. INTERNAL static void
  506. MouseInputProc(dummy, value)
  507.     ClientData dummy;        /* Not used. */
  508.     int value;            /* Character that arrived from UART. */
  509. {
  510.     char c;
  511.     Time time;
  512.     Event *eventPtr;
  513.  
  514.     /*
  515.      * Mouse characters arrive in bunches, with the first character
  516.      * of each bunch specially marked.  A simple state machine here
  517.      * keeps track of where we are in the bunch.
  518.      */
  519.  
  520. #define WAIT_SYNC    0
  521. #define WAIT_DELTA_X1    1
  522. #define WAIT_DELTA_Y1    2
  523. #define WAIT_DELTA_X2    3
  524. #define WAIT_DELTA_Y2    4
  525.  
  526. #define NUM_STATES    5
  527. #define SYNC_BIT     0x80
  528.  
  529.     static int curState = WAIT_SYNC;
  530.     static Mouse_Event event;
  531.  
  532.     /*
  533.      * Discard any special characters (breaks, etc.).
  534.      */
  535.  
  536.     if (DEV_TTY_IS_CONTROL(value)) {
  537.     return;
  538.     }
  539.     c = value;
  540.  
  541.     /*
  542.      * The check below keeps our state machine back in sync with the
  543.      * mouse by discarding characters up to the beginning of the next
  544.      * sequence.
  545.      */
  546.  
  547.     if ((curState == WAIT_SYNC) && !(c & SYNC_BIT)) {
  548.     return;
  549.     }
  550.     switch (curState) {
  551.     case WAIT_SYNC:
  552.         event.key = c & 0x7;
  553.         break;
  554.     case WAIT_DELTA_X1:
  555.         event.deltaX = (int) c;
  556.         break;
  557.     case WAIT_DELTA_Y1:
  558.         event.deltaY = (int) c;
  559.         break;
  560.     case WAIT_DELTA_X2:
  561.         event.deltaX += (int) c;
  562.         break;
  563.     case WAIT_DELTA_Y2:
  564.         event.deltaY += (int) c;
  565.         event.flags = MOUSE_EVENT;
  566.         Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  567.         event.time = (time.seconds*1000) + (time.microseconds/1000);
  568.         eventPtr = (Event *) malloc(sizeof(Event));
  569.         List_InitElement(&eventPtr->links);
  570.         eventPtr->event = event;
  571.         List_Insert(&eventPtr->links, LIST_ATREAR(&eventList));
  572.         dev_LastConsoleInput = time;
  573.         Fsio_DevNotifyReader(token);
  574.         break;
  575.     }
  576.     curState++;
  577.     if (curState >= NUM_STATES) {
  578.     curState = 0;
  579.     }
  580. }
  581.  
  582. /*
  583.  *----------------------------------------------------------------------
  584.  *
  585.  * KbdInputProc --
  586.  *
  587.  *    This procedure is invoked at background level (i.e in a kernel
  588.  *    process) to handle input characters from the keyboard UART.
  589.  *    This procedure is invoked only when the mouse device is open.
  590.  *    The caller is expected to have acquired the tty monitor lock.
  591.  *
  592.  * Results:
  593.  *    None.
  594.  *
  595.  * Side effects:
  596.  *    The input character is converted to an event, which is then
  597.  *    enqueued on an input queue.
  598.  *
  599.  *----------------------------------------------------------------------
  600.  */
  601.  
  602. /* ARGSUSED */
  603. INTERNAL static void
  604. KbdInputProc(dummy, value)
  605.     ClientData dummy;        /* Not used. */
  606.     int value;            /* Character that arrived from UART:
  607.                  * identifies which key, and whether up
  608.                  * or down transition. */
  609. {
  610.     register Event *eventPtr;
  611.     Time time;
  612.  
  613.     /*
  614.      * Throw away control events and anything corresponding to a console
  615.      * command.
  616.      */
  617.  
  618.     if (DEV_TTY_IS_CONTROL(value)) {
  619.     return;
  620.     }
  621.     if (DevConsoleConvertKeystroke(value) == -2) {
  622.     return;
  623.     }
  624.  
  625.     eventPtr = (Event *) malloc(sizeof(Event));
  626.     List_InitElement(&eventPtr->links);
  627.     eventPtr->event.flags = KEYBOARD_EVENT;
  628.     if (value & 0x80) {
  629.     eventPtr->event.flags |= KEY_UP;
  630.     }
  631.     eventPtr->event.key = value & 0x7f;
  632.     eventPtr->event.deltaX = 0;
  633.     eventPtr->event.deltaY = 0;
  634.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  635.     eventPtr->event.time = (time.seconds*1000) + (time.microseconds/1000);
  636.     List_Insert(&eventPtr->links, LIST_ATREAR(&eventList));
  637.     dev_LastConsoleInput = time;
  638.     Fsio_DevNotifyReader(token);
  639. }
  640.  
  641. /*
  642.  *----------------------------------------------------------------------
  643.  *
  644.  * MouseOutputProc --
  645.  *
  646.  *    This procedure is called at interrupt level to fetch the
  647.  *    next output character for the mouse device (these output
  648.  *    characters go to the keyboard).
  649.  *
  650.  * Results:
  651.  *    Returns the next output character, or -1 if the output buffer
  652.  *    is empty.
  653.  *
  654.  * Side effects:
  655.  *    May wake up processes waiting to write to this device because
  656.  *    the output buffer was full.
  657.  *
  658.  *----------------------------------------------------------------------
  659.  */
  660.  
  661. static int
  662. MouseOutputProc()
  663. {
  664.     int result;
  665.  
  666.     result = outputBuffer;
  667.     if (result != -1) {
  668.     outputBuffer = -1;
  669.     if (mouseTty.openCount > 0) {
  670.         Fsio_DevNotifyWriter(token);
  671.     } else {
  672.         Proc_CallFunc(MouseDelayedClose, (ClientData) NIL, 0);
  673.     }
  674.     }
  675.     return result;
  676. }
  677.  
  678. /*
  679.  *----------------------------------------------------------------------
  680.  *
  681.  * Dev_ConsoleReset --
  682.  *
  683.  *    This procedure is called as a console command procedure to
  684.  *    switch console keyboard input back and forth between /dev/mouse
  685.  *    and /dev/console.
  686.  *
  687.  * Results:
  688.  *    None.
  689.  *
  690.  * Side effects:
  691.  *    None.
  692.  *
  693.  *----------------------------------------------------------------------
  694.  */
  695.  
  696. void
  697. Dev_ConsoleReset(toConsole)
  698.     int toConsole;            /* 1 means make keystrokes go to
  699.                      * console.  0 means make keystrokes
  700.                      * go to mouse device. */
  701. {
  702.     if (toConsole) {
  703.     DevReleaseKeyboard();
  704.     } else {
  705.     keyboardPtr = DevGrabKeyboard(KbdInputProc, (ClientData) 0,
  706.         MouseOutputProc, (ClientData) 0);
  707.     }
  708. }
  709.